package com.thesis.manage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.thesis.manage.common.redis.RedisDao;
import com.thesis.manage.common.utils.Result;
import com.thesis.manage.domain.Admin;
import com.thesis.manage.domain.Student;
import com.thesis.manage.domain.Teacher;
import com.thesis.manage.service.*;
import com.thesis.manage.service.constant.ErrorMessage;
import com.thesis.manage.service.model.RoleEnum;
import com.thesis.manage.service.model.StateCodeEnum;
import com.thesis.manage.service.model.UserActivityStateEnum;
import com.thesis.manage.service.module.dto.UserLoginDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.util.UUID;

/**
 * @author php
 * @date 2018/1/23
 */
@Service
public class LoginRegisterServiceImpl implements LoginRegisterService {
    private static final Integer EXPIRE_TIME = 60 * 30;
    @Resource
    private TeacherService teacherService;

    @Resource
    private StudentService studentService;

    @Resource
    private AdminService adminService;

    @Resource
    private RedisDao redisDao;

    @Resource
    private TeacherRoleService teacherRoleService;

    @Override
    public Result register(String account, String password, Integer type) {
        Result result = new Result();
        boolean sure = StringUtils.isBlank(account) || StringUtils.isBlank(password) || type == null;
        Assert.state(!sure, "用户名或密码为空");
        if (RoleEnum.TEACHER.getValue().intValue() == type) {
            //执行老师注册
            result = this.registerTeacher(account, password);
        }
        if (RoleEnum.STUDENT.getValue().intValue() == type) {
            //执行学生注册
            result = this.registerStudent(account, password);
        }
        if (RoleEnum.ADMIN.getValue().intValue() == type) {
            //管理员注册
            result = this.registerAdmin(account, password);
        }
        return result;
    }

    @Override
    public Result login(String account, String password, Integer type) {
        boolean sure = StringUtils.isBlank(account) || StringUtils.isBlank(password) || type == null;
        Assert.state(!sure, "用户名或密码不能为空");
        //生成token
        String token = UUID.randomUUID().toString();
        UserLoginDTO userLoginDTO;
        if (RoleEnum.TEACHER.getValue().intValue() == type) {
            //执行老师登录
            Teacher teacher = this.teacherService.findByTeacherNumber(account);
            if (teacher != null) {
                boolean isSuccess = DigestUtils.md5DigestAsHex(password.getBytes()).equals(teacher.getPassword());
                if (isSuccess) {
                    //修改用户状态(在线)
                    Teacher update = new Teacher();
                    update.setId(teacher.getId());
                    update.setStatus(UserActivityStateEnum.ON_LINE.getValue());
                    this.teacherService.save(update);
                    //缓存用户数据到redis
                    userLoginDTO = new UserLoginDTO();
                    teacher.setPassword(null);
                    String data = JSONObject.toJSONString(teacher);
                    this.redisDao.setex(token, EXPIRE_TIME, data);
                    userLoginDTO.setToken(token);
                    userLoginDTO.setUserInfo(data);
                    //查询老师权限
                    String roles = this.teacherRoleService.findRoles(teacher.getId());
                    userLoginDTO.setRoles(roles);
                    return Result.ok(JSONObject.toJSONString(userLoginDTO));
                } else {
                    return Result.build(StateCodeEnum.FAILED.getValue(), "用户名或密码错误");
                }
            }
        }
        if (RoleEnum.STUDENT.getValue().intValue() == type) {
            //执行学生登录
            Student student = this.studentService.findByStudentNumber(account);
            if (student != null) {
                System.out.println(student.getPassword());
                System.out.println(DigestUtils.md5DigestAsHex(password.getBytes()));
                boolean isSuccess = DigestUtils.md5DigestAsHex(password.getBytes()).equals(student.getPassword());
                if (isSuccess) {
                    //修改用户状态(在线)
                    Student update = new Student();
                    update.setStatus(UserActivityStateEnum.ON_LINE.getValue());
                    update.setId(student.getId());
                    this.studentService.save(update);
                    //缓存用户数据到redis
                    userLoginDTO = new UserLoginDTO();
                    student.setPassword(null);
                    String data = JSONObject.toJSONString(student);
                    this.redisDao.setex(token, EXPIRE_TIME, data);
                    userLoginDTO.setUserInfo(data);
                    userLoginDTO.setToken(token);
                    return Result.ok(JSONObject.toJSONString(userLoginDTO));
                } else {
                    return Result.build(StateCodeEnum.FAILED.getValue(), "用户名或密码错误");
                }
            }
        }
        if (RoleEnum.ADMIN.getValue().intValue() == type) {
            //执行管理员登录
            Admin admin = this.adminService.findByName(account);
            if (admin != null) {
                boolean isSuccess = DigestUtils.md5DigestAsHex(password.getBytes()).equals(admin.getPassword());
                if (isSuccess) {
                    //修改用户状态(在线)
                    Admin update = new Admin();
                    update.setStatus(UserActivityStateEnum.ON_LINE.getValue());
                    update.setId(admin.getId());
                    this.adminService.save(update);
                    //缓存用户数据到redis
                    userLoginDTO = new UserLoginDTO();
                    admin.setPassword(null);
                    String data = JSONObject.toJSONString(admin);
                    this.redisDao.setex(token, EXPIRE_TIME, data);
                    userLoginDTO.setUserInfo(data);
                    userLoginDTO.setToken(token);
                    return Result.ok(JSONObject.toJSONString(userLoginDTO));
                } else {
                    return Result.build(StateCodeEnum.FAILED.getValue(), "用户名或密码错误");
                }
            }
        }
        return Result.build(StateCodeEnum.RESOUCEERROR.getValue(), "用户不存在");
    }

    @Override
    public Result findUserByToken(String token) {
        //验证用户是否登录或token是否失效
        Result result = this.checkToken(token);
        if (result.getStatus() != StateCodeEnum.SUCCESS.getValue().intValue()) {
            return result;
        }
        String json = this.redisDao.get(token);
        return Result.ok(json);
    }

    @Override
    public Result checkToken(String token) {
        boolean sure = StringUtils.isBlank(token);
        if (sure) {
            return Result.build(StateCodeEnum.FAILED.getValue(), "用户未登录");
        }
        boolean exists = this.redisDao.exists(token);
        if (exists) {
            return Result.ok();
        }
        return Result.build(StateCodeEnum.FAILED.getValue(), "token已失效");
    }

    @Override
    public void expire(String token, Integer type) {
        this.redisDao.expire(token, type);
//        Result result = this.findUserByToken(token);
//        if (RoleEnum.TEACHER.getValue().intValue() == type) {
//            Teacher data = (Teacher) result.getData();
//            Teacher teacher = this.teacherService.findById(data.getId());
//            teacher.setPassword(null);
//            this.redisDao.setex(token, EXPIRE_TIME, JSONObject.toJSONString(teacher));
//        }
//        if (RoleEnum.STUDENT.getValue().intValue() == type) {
//            Student data = (Student) result.getData();
//            Student student = this.studentService.findById(data.getId());
//            student.setPassword(null);
//            this.redisDao.setex(token, EXPIRE_TIME, JSONObject.toJSONString(student));
//        }
//        if (RoleEnum.ADMIN.getValue().intValue() == type) {
//            Admin data = (Admin) result.getData();
//            Student student = this.studentService.findById(data.getId());
//            student.setPassword(null);
//            this.redisDao.setex(token, EXPIRE_TIME, JSONObject.toJSONString(student));
//        }
    }

    @Override
    public Result logout(String token) {
        Result result = this.checkToken(token);
        if (result.getStatus().intValue() != StateCodeEnum.SUCCESS.getValue()) {
            return result;
        }
        this.redisDao.del(token);
        return Result.ok();
    }

    @Override
    public void updatePassword(Long id, String password) {
        Assert.notNull(password, ErrorMessage.PARAMS_IS_NULL);
        Student student = new Student();
        student.setId(id);
        student.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        this.studentService.save(student);
    }


    /**
     * 教师注册
     *
     * @param account  账号
     * @param password 密码
     * @return Result
     */
    private Result registerTeacher(String account, String password) {
        Teacher one = this.teacherService.findByTeacherNumber(account);
        if (one != null) {
            return Result.build(StateCodeEnum.RESOUCEERROR.getValue(), "用户已存在");
        } else {
            Teacher teacher = new Teacher();
            teacher.setTeacherNumber(account);
            teacher.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
            teacher.setStatus(UserActivityStateEnum.OFF_LINE.getValue());
            this.teacherService.save(teacher);
            return Result.ok();
        }
    }

    /**
     * 学生注册
     *
     * @param account  账号
     * @param password 密码
     * @return Result
     */
    private Result registerStudent(String account, String password) {
        Student one = this.studentService.findByStudentNumber(account);
        if (one != null) {
            return Result.build(StateCodeEnum.RESOUCEERROR.getValue(), "用户已存在");
        } else {
            Student student = new Student();
            student.setStudentNumber(account);
            student.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
            student.setStatus(UserActivityStateEnum.OFF_LINE.getValue());
            this.studentService.save(student);
            return Result.ok();
        }
    }

    /**
     * 管理员注册
     *
     * @param account  账号
     * @param password 密码
     * @return Result
     */
    private Result registerAdmin(String account, String password) {
        Admin one = this.adminService.findByName(account);
        if (one != null) {
            return Result.build(StateCodeEnum.RESOUCEERROR.getValue(), "用户已存在");
        } else {
            Admin admin = new Admin();
            admin.setName(account);
            admin.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
            admin.setStatus(UserActivityStateEnum.OFF_LINE.getValue());
            this.adminService.save(admin);
            return Result.ok();
        }
    }


}
